/*
 *  Copyright (C) <2009>  Pavel Vakeš <pavel.vakes@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "messages_view.h"
#include <KDebug>

// Qt

#include <QtGui/QMouseEvent>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <QtGui/QScrollBar>
#include <QtGui/QHeaderView>
#include <QtGui/QStandardItemModel>

//KDE
#include <KDebug>
#include <KIconLoader>
#include <KColorScheme>
#include <KGlobalSettings>

//Plasma
#include <Plasma/Delegate>

MessagesView::MessagesView(QWidget *parent)
    : QTreeView(parent)
{
//    setIconSize(QSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium));
//    setRootIsDecorated(true);
    setHeaderHidden(true);
    setMouseTracking(true);
}

MessagesView::~MessagesView()
{

}

QModelIndex MessagesView::indexAt(const QPoint& point) const
{
    // simple linear search through the item rects, this will
    // be inefficient when the viewport is large
//    QHashIterator<QModelIndex,QRect> iter(itemRects);
//    while (iter.hasNext()) {
//        iter.next();
//        if (iter.value().contains(point + QPoint(0, verticalOffset()))) {
//            return iter.key();
//        }
//    }
    const int rows = model()->rowCount();

	if (point.y() > 0 && point.y() < rows * ROW_HEIGHT) return model()->index(point.y() / ROW_HEIGHT, 0);

    return QModelIndex();
}
//
void MessagesView::resizeEvent(QResizeEvent * event)
{
    //the columns after the first are squares KIconLoader::SizeMedium x KIconLoader::SizeMedium,
    //the first column takes all the remaining space
//    calculateRects();
	kDebug() << header()->size();

    if (header()->count() > 0) {
        const int newWidth = event->size().width() -
                             (header()->count()-1)*(sizeHintForRow(0));
//        kDebug() << newWidth;
//        setMinimumWidth(newWidth);
//        header()->resizeSection(0, newWidth);
    }

//    horizontalScrollBar()->update();
}
//
void MessagesView::mouseMoveEvent(QMouseEvent *event)
{
    const QModelIndex itemUnderMouse = indexAt(event->pos());
    if (itemUnderMouse != m_hoveredIndex && itemUnderMouse.isValid() &&
        state() == NoState) {
        update(itemUnderMouse);
        update(m_hoveredIndex);
        m_hoveredIndex = itemUnderMouse;
        setCurrentIndex(m_hoveredIndex);
    } else if (!itemUnderMouse.isValid()) {
        m_hoveredIndex = QModelIndex();
        setCurrentIndex(m_hoveredIndex);
    }

    QTreeView::mouseMoveEvent(event);
}

void MessagesView::mousePressEvent(QMouseEvent *event)
{
    const QModelIndex itemUnderMouse = indexAt(event->pos());
    //don't pass click for header
    if (event->button() != Qt::LeftButton || model()->hasChildren(itemUnderMouse)) {
        return;
    }

    QAbstractItemView::mousePressEvent(event);
}

void MessagesView::leaveEvent(QEvent *event)
{
    Q_UNUSED(event)
    if (m_hoveredIndex.isValid()) {
        const QModelIndex oldHoveredIndex = m_hoveredIndex;
        m_hoveredIndex = QModelIndex();
        setCurrentIndex(m_hoveredIndex);
        update(oldHoveredIndex);
    }
}

QModelIndex MessagesView::moveCursor(CursorAction cursorAction,Qt::KeyboardModifiers modifiers )
{
    m_hoveredIndex = QModelIndex();

    return QTreeView::moveCursor(cursorAction, modifiers );
}

//void MessagesView::calculateRects()
//{
//    kDebug()<<"beforeModel";
//    if (!model()) {
//        return;
//    }
//    kDebug()<<"afterModel";
//
//    itemRects.clear();
//    int verticalOffset = TOP_OFFSET;
//
//    const int rows = model()->rowCount(rootIndex());
//    const int cols = header()->count();
//    kDebug() << "painting" << rows << "rows" << cols << "columns";
//
//
//    for (int i = 0; i < rows; ++i) {
//        for (int j = 0; j < cols; ++j) {
//            const QModelIndex index = model()->index(i, j, rootIndex());
//    kDebug()<<index << model()->hasChildren(index);
//            if (model()->hasChildren(index)) {
//                QRect itemRect(QPoint(HEADER_LEFT_MARGIN, verticalOffset),
//                               QSize(width() - HEADER_LEFT_MARGIN, HEADER_HEIGHT));
//                verticalOffset += itemRect.size().height();
//                itemRects.insert(index, itemRect);
//
//                QStandardItemModel * currentModel = dynamic_cast<QStandardItemModel *>(model());
//                QStandardItem *currentItem = currentModel->itemFromIndex(index);
//                // we display the children of this item
//                for (int k = 0; k < currentItem->rowCount(); ++k) {
//                    for (int l = 0; l < currentItem->columnCount(); ++l) {
//                        QStandardItem *childItem = currentItem->child(k, l);
//                        QModelIndex childIndex = childItem->index();
//                        QRect itemChildRect;
//                        if (l % 2 == 0) {
//                            QSize size(width() - COLUMN_EJECT_SIZE,sizeHintForIndex(index).height());
//                            itemChildRect = QRect(QPoint(HEADER_LEFT_MARGIN, verticalOffset), size);
//                            itemRects.insert(childIndex, itemChildRect);
//                        } else {
//                            QSize size(COLUMN_EJECT_SIZE - style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 2,
//                                       sizeHintForIndex(index).height());
//                            itemChildRect = QRect(QPoint(width() - (COLUMN_EJECT_SIZE - COLUMN_EJECT_MARGIN ),
//                                                  verticalOffset), size);
//                            itemRects.insert(childIndex, itemChildRect);
//                            verticalOffset += itemChildRect.size().height();
//                        }
//                    }
//                }
//            }
//        }
//    }
//}
//
void MessagesView::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    if (!model()) {
        return;
    }
    int verticalOffset = VIEW_TOP_OFFSET;

    QPainter painter(viewport());
    painter.setRenderHint(QPainter::Antialiasing);

    const int rows = model()->rowCount();
    QModelIndex index;
    QRect itemRect;

    for (int i = 0; i < rows; ++i) {
    	// Status
		index = model()->index(i, 0);

		itemRect = QRect(QPoint(COL_MARGIN_SIDE, verticalOffset), QSize(COL_STATUS_WIDTH, sizeHintForIndex(index).height()));

		paintItem(painter, itemRect, index);

		// Time
		index = model()->index(i, 0);

		itemRect = QRect(QPoint(COL_MARGIN_SIDE + COL_STATUS_WIDTH, verticalOffset), QSize(COL_TIME_WIDTH + COL_MARGIN_SIDE, sizeHintForIndex(index).height()));
//		QRect itemRect(QPoint(HEADER_LEFT_MARGIN, verticalOffset), QSize(width() - HEADER_LEFT_MARGIN - style()->pixelMetric(QStyle::PM_ScrollBarExtent), sizeHintForIndex(index).height()));

		paintItem(painter, itemRect, index);

		verticalOffset += itemRect.size().height();
    }

//    while (it.itemData().hasNext()) {
//        it.itemData().next();
//        QRect itemRect = it.value();
//        if (event->region().contains(itemRect)) {
//            QModelIndex index = it.key();
//            if (model()->hasChildren(index)) {
//                kDebug()<<"header"<<itemRect;
////                paintHeaderItem(painter, itemRect, index);
//            } else {
//                paintItem(painter, itemRect, index);
//            }
//        }
//    }
}
//
//void MessagesView::paintHeaderItem(QPainter &painter, const QRect &itemRect, const QModelIndex &index)
//{
//    QStyleOptionViewItem option = viewOptions();
//    option.rect = itemRect;
//    const int rightMargin = style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 6;
//    const int dy = HEADER_TOP_MARGIN;
//
//    painter.save();
//    painter.setRenderHint(QPainter::Antialiasing, false);
//
//    QLinearGradient gradient(option.rect.topLeft(), option.rect.topRight());
//    gradient.setColorAt(0.0, Qt::transparent);
//    gradient.setColorAt(0.1, option.palette.midlight().color());
//    gradient.setColorAt(0.5, option.palette.mid().color());
//    gradient.setColorAt(0.9, option.palette.midlight().color());
//    gradient.setColorAt(1.0, Qt::transparent);
//    painter.setPen(QPen(gradient, 1));
//
//    painter.drawLine(option.rect.x() + 6, option.rect.y() + dy + 2,
//                     option.rect.right() - rightMargin , option.rect.y() + dy + 2);
//    painter.setFont(KGlobalSettings::smallestReadableFont());
//    painter.setPen(QPen(KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText), 0));
//    QString text = index.data(Qt::DisplayRole).value<QString>();
//    kDebug() << text;
//    painter.drawText(option.rect.adjusted(0, dy, -rightMargin, 0),
//                    Qt::AlignVCenter|Qt::AlignRight, text);
//    painter.restore();
//}
//
void MessagesView::paintItem(QPainter &painter, const QRect &itemRect, const QModelIndex &index)
{
    QStyleOptionViewItem option = viewOptions();
    option.rect = itemRect;

    if (selectionModel()->isSelected(index)) {
        option.state |= QStyle::State_Selected;
    }

    if (index == m_hoveredIndex) {
        option.state |= QStyle::State_MouseOver;
    }

    if (index == currentIndex()) {
        option.state |= QStyle::State_HasFocus;
    }

    itemDelegate(index)->paint(&painter,option,index);
}

QRect MessagesView::visualRect ( const QModelIndex & index ) const
{
	int verticalOffset = VIEW_TOP_OFFSET;

	QRect itemRect(QPoint(COL_MARGIN_SIDE, verticalOffset + index.row() * sizeHintForIndex(index).height()), QSize(width() - COL_MARGIN_SIDE - style()->pixelMetric(QStyle::PM_ScrollBarExtent), sizeHintForIndex(index).height()));

	return itemRect;
}


#include "messages_view.moc"
